home *** CD-ROM | disk | FTP | other *** search
- # Gedit snippets plugin
- # Copyright (C) 2005-2006 Jesse van den Kieboom <jesse@icecrew.nl>
- #
- # This program is free software; you can redistribute it and/or modify
- # it under the terms of the GNU General Public License as published by
- # the Free Software Foundation; either version 2 of the License, or
- # (at your option) any later version.
- #
- # This program is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU General Public License for more details.
- #
- # You should have received a copy of the GNU General Public License
- # along with this program; if not, write to the Free Software
- # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
- import os
- import tempfile
- import shutil
-
- import gobject
- import gtk
- from gtk import gdk
- import gtksourceview2 as gsv
- import pango
- import gedit
- import gio
-
- from Snippet import Snippet
- from Helper import *
- from Library import *
- from Importer import *
- from Exporter import *
- from Document import Document
-
- class Manager:
- NAME_COLUMN = 0
- SORT_COLUMN = 1
- OBJ_COLUMN = 2
- TARGET_URI = 105
-
- model = None
- drag_icons = ('gnome-mime-application-x-tarz', 'gnome-package', 'package')
- default_export_name = _('Snippets archive') + '.tar.gz'
- dragging = False
- dnd_target_list = [('text/uri-list', 0, TARGET_URI)]
-
- def __init__(self, datadir):
- self.datadir = datadir
- self.snippet = None
- self.dlg = None
- self._temp_export = None
- self.snippets_doc = None
- self.manager = None
- self.default_size = None
-
- self.key_press_id = 0
- self.tooltips = gtk.Tooltips()
- self.run()
-
- def get_language_snippets(self, path, name = None):
- library = Library()
-
- name = self.get_language(path)
- nodes = library.get_snippets(name)
-
- return nodes
-
- def add_new_snippet_node(self, parent):
- return self.model.append(parent, ('<i>' + _('Add a new snippet...') + \
- '</i>', '', None))
-
- def fill_language(self, piter, expand=True):
- # Remove all children
- child = self.model.iter_children(piter)
-
- while child and self.model.remove(child):
- True
-
- path = self.model.get_path(piter)
- nodes = self.get_language_snippets(path)
- language = self.get_language(path)
-
- Library().ref(language)
-
- if nodes:
- for node in nodes:
- self.add_snippet(piter, node)
- else:
- # Add node that tells there are no snippets currently
- self.add_new_snippet_node(piter)
-
- if expand:
- self.tree_view.expand_row(path, False)
-
- def build_model(self, force_reload = False):
- window = gedit.app_get_default().get_active_window()
-
- if window:
- view = window.get_active_view()
-
- if not view:
- current_lang = None
- else:
- current_lang = view.get_buffer().get_language()
- source_view = self['source_view_snippet']
-
- else:
- current_lang = None
-
- tree_view = self['tree_view_snippets']
- expand = None
-
- if not self.model or force_reload:
- self.model = gtk.TreeStore(str, str, object)
- self.model.set_sort_column_id(self.SORT_COLUMN, gtk.SORT_ASCENDING)
- manager = self.get_language_manager()
- langs = gedit.language_manager_list_languages_sorted(manager, True)
-
- piter = self.model.append(None, (_('Global'), '', None))
- # Add dummy node
- self.model.append(piter, ('', '', None))
-
- nm = None
-
- if current_lang:
- nm = current_lang.get_name()
-
- for lang in langs:
- name = lang.get_name()
- parent = self.model.append(None, (name, name, lang))
-
- # Add dummy node
- self.model.append(parent, ('', '', None))
-
- if (nm == name):
- expand = parent
- else:
- if current_lang:
- piter = self.model.get_iter_first()
- nm = current_lang.get_name()
-
- while piter:
- lang = self.model.get_value(piter, \
- self.SORT_COLUMN)
-
- if lang == nm:
- expand = piter
- break;
-
- piter = self.model.iter_next(piter)
-
- tree_view.set_model(self.model)
-
- if not expand:
- expand = self.model.get_iter_root()
-
- tree_view.expand_row(self.model.get_path(expand), False)
- self.select_iter(expand)
-
- def get_cell_data_pixbuf_cb(self, column, cell, model, iter):
- s = model.get_value(iter, self.OBJ_COLUMN)
-
- snippet = isinstance(s, SnippetData)
-
- if snippet and not s.valid:
- cell.set_property('stock-id', gtk.STOCK_DIALOG_ERROR)
- else:
- cell.set_property('stock-id', None)
-
- cell.set_property('xalign', 1.0)
-
- def get_cell_data_cb(self, column, cell, model, iter):
- s = model.get_value(iter, self.OBJ_COLUMN)
-
- snippet = isinstance(s, SnippetData)
-
- cell.set_property('editable', snippet)
- cell.set_property('markup', model.get_value(iter, self.NAME_COLUMN))
-
- def on_tree_view_drag_data_get(self, widget, context, selection_data, info, time):
- gfile = gio.File(self._temp_export)
- selection_data.set_uris([gfile.get_uri()])
-
- def on_tree_view_drag_begin(self, widget, context):
- self.dragging = True
-
- if self._temp_export:
- shutil.rmtree(os.path.dirname(self._temp_export))
- self._temp_export = None
-
- if self.dnd_name:
- context.set_icon_name(self.dnd_name, 0, 0)
-
- dirname = tempfile.mkdtemp()
- filename = os.path.join(dirname, self.default_export_name)
-
- # Generate temporary file name
- self.export_snippets(filename, False)
- self._temp_export = filename
-
- def on_tree_view_drag_end(self, widget, context):
- self.dragging = False
-
- def on_tree_view_drag_data_received(self, widget, context, x, y, selection, info, timestamp):
- uris = selection.get_uris()
-
- self.import_snippets(uris)
-
- def on_tree_view_drag_motion(self, widget, context, x, y, timestamp):
- # Return False if we are dragging
- if self.dragging:
- return False
-
- # Check uri target
- if not gtk.targets_include_uri(context.targets):
- return False
-
- # Check action
- action = None
- if context.suggested_action == gdk.ACTION_COPY:
- action = gdk.ACTION_COPY
- else:
- for act in context.actions:
- if act == gdk.ACTION_COPY:
- action = gdk.ACTION_COPY
- break
-
- if action == gdk.ACTION_COPY:
- context.drag_status(gdk.ACTION_COPY, timestamp)
- return True
- else:
- return False
-
- def build_dnd(self):
- tv = self.tree_view
-
- # Set it as a drag source for exporting snippets
- tv.drag_source_set(gdk.BUTTON1_MASK, self.dnd_target_list, gdk.ACTION_DEFAULT | gdk.ACTION_COPY)
-
- # Set it as a drag destination for importing snippets
- tv.drag_dest_set(gtk.DEST_DEFAULT_HIGHLIGHT | gtk.DEST_DEFAULT_DROP,
- self.dnd_target_list, gdk.ACTION_DEFAULT | gdk.ACTION_COPY)
-
- tv.connect('drag_data_get', self.on_tree_view_drag_data_get)
- tv.connect('drag_begin', self.on_tree_view_drag_begin)
- tv.connect('drag_end', self.on_tree_view_drag_end)
- tv.connect('drag_data_received', self.on_tree_view_drag_data_received)
- tv.connect('drag_motion', self.on_tree_view_drag_motion)
-
- theme = gtk.icon_theme_get_for_screen(tv.get_screen())
-
- self.dnd_name = None
- for name in self.drag_icons:
- icon = theme.lookup_icon(name, gtk.ICON_SIZE_DND, 0)
-
- if icon:
- self.dnd_name = name
- break
-
- def build_tree_view(self):
- self.tree_view = self['tree_view_snippets']
-
- self.column = gtk.TreeViewColumn(None)
-
- self.renderer = gtk.CellRendererText()
- self.column.pack_start(self.renderer, False)
- self.column.set_cell_data_func(self.renderer, self.get_cell_data_cb)
-
- renderer = gtk.CellRendererPixbuf()
- self.column.pack_start(renderer, True)
- self.column.set_cell_data_func(renderer, self.get_cell_data_pixbuf_cb)
-
- self.tree_view.append_column(self.column)
-
- self.renderer.connect('edited', self.on_cell_edited)
- self.renderer.connect('editing-started', self.on_cell_editing_started)
-
- selection = self.tree_view.get_selection()
- selection.set_mode(gtk.SELECTION_MULTIPLE)
- selection.connect('changed', self.on_tree_view_selection_changed)
-
- self.build_dnd()
-
- def get_language_manager(self):
- if not self.manager:
- dirs = []
-
- for d in Library().systemdirs:
- dirs.append(os.path.join(d, 'lang'))
-
- self.manager = gsv.LanguageManager()
- self.manager.set_search_path(dirs + self.manager.get_search_path())
-
- return self.manager
-
- def build(self):
- self.builder = gtk.Builder()
- self.builder.add_from_file(os.path.join(self.datadir, 'ui', 'snippets.ui'))
-
- handlers_dic = {
- 'on_dialog_snippets_response': self.on_dialog_snippets_response,
- 'on_dialog_snippets_destroy': self.on_dialog_snippets_destroy,
- 'on_button_new_snippet_clicked': self.on_button_new_snippet_clicked,
- 'on_button_import_snippets_clicked': self.on_button_import_snippets_clicked,
- 'on_button_export_snippets_clicked': self.on_button_export_snippets_clicked,
- 'on_button_remove_snippet_clicked': self.on_button_remove_snippet_clicked,
- 'on_entry_tab_trigger_focus_out': self.on_entry_tab_trigger_focus_out,
- 'on_entry_tab_trigger_changed': self.on_entry_tab_trigger_changed,
- 'on_entry_accelerator_focus_out': self.on_entry_accelerator_focus_out,
- 'on_entry_accelerator_focus_in': self.on_entry_accelerator_focus_in,
- 'on_entry_accelerator_key_press': self.on_entry_accelerator_key_press,
- 'on_source_view_snippet_focus_out': self.on_source_view_snippet_focus_out,
- 'on_tree_view_snippets_row_expanded': self.on_tree_view_snippets_row_expanded,
- 'on_tree_view_snippets_key_press': self.on_tree_view_snippets_key_press}
-
- self.builder.connect_signals(handlers_dic)
-
- self.build_tree_view()
- self.build_model()
-
- image = self['image_remove']
- image.set_from_stock(gtk.STOCK_REMOVE, gtk.ICON_SIZE_SMALL_TOOLBAR)
-
- source_view = self['source_view_snippet']
- manager = self.get_language_manager()
- lang = manager.get_language('snippets')
-
- if lang:
- source_view.get_buffer().set_highlight_syntax(True)
- source_view.get_buffer().set_language(lang)
- self.snippets_doc = Document(None, source_view)
-
- entry = self['combo_drop_targets'].child
- entry.connect('focus-out-event', self.on_entry_drop_targets_focus_out)
- entry.connect('drag-data-received', self.on_entry_drop_targets_drag_data_received)
-
- lst = entry.drag_dest_get_target_list()
- lst = gtk.target_list_add_uri_targets(entry.drag_dest_get_target_list(), self.TARGET_URI)
- entry.drag_dest_set_target_list(lst)
-
- self.dlg = self['dialog_snippets']
-
- if self.default_size:
- self.dlg.set_default_size(*self.default_size)
-
- def __getitem__(self, key):
- return self.builder.get_object(key)
-
- def is_filled(self, piter):
- if not self.model.iter_has_child(piter):
- return True
-
- child = self.model.iter_children(piter)
- nm = self.model.get_value(child, self.NAME_COLUMN)
- obj = self.model.get_value(child, self.OBJ_COLUMN)
-
- return (obj or nm)
-
- def fill_if_needed(self, piter, expand=True):
- if not self.is_filled(piter):
- self.fill_language(piter, expand)
-
- def find_iter(self, parent, snippet):
- self.fill_if_needed(parent)
- piter = self.model.iter_children(parent)
-
- while (piter):
- node = self.model.get_value(piter, self.OBJ_COLUMN)
-
- if node == snippet.data:
- return piter
-
- piter = self.model.iter_next(piter)
-
- return None
-
- def selected_snippets_state(self):
- snippets = self.selected_snippets(False)
- override = False
- remove = False
- system = False
-
- for snippet in snippets:
- if not snippet:
- continue
-
- if snippet.is_override():
- override = True
- elif snippet.can_modify():
- remove = True
- else:
- system = True
-
- # No need to continue if both are found
- if override and remove:
- break
-
- return (override, remove, system)
-
- def update_buttons(self):
- button_remove = self['button_remove_snippet']
- button_new = self['button_new_snippet']
- image_remove = self['image_remove']
-
- button_new.set_sensitive(self.language_path != None)
- override, remove, system = self.selected_snippets_state()
-
- if not (override ^ remove) or system:
- button_remove.set_sensitive(False)
- image_remove.set_from_stock(gtk.STOCK_DELETE, gtk.ICON_SIZE_BUTTON)
- else:
- button_remove.set_sensitive(True)
-
- if override:
- image_remove.set_from_stock(gtk.STOCK_UNDO, gtk.ICON_SIZE_BUTTON)
- tooltip = _('Revert selected snippet')
- else:
- image_remove.set_from_stock(gtk.STOCK_DELETE, gtk.ICON_SIZE_BUTTON)
- tooltip = _('Delete selected snippet')
-
- self.tooltips.set_tip(button_remove, tooltip)
-
- def snippet_changed(self, piter = None):
- if piter:
- node = self.model.get_value(piter, self.OBJ_COLUMN)
- s = Snippet(node)
- else:
- s = self.snippet
- piter = self.find_iter(self.model.get_iter(self.language_path), s)
-
- if piter:
- nm = s.display()
-
- self.model.set(piter, self.NAME_COLUMN, nm, self.SORT_COLUMN, nm)
- self.update_buttons()
- self.entry_tab_trigger_update_valid()
-
- return piter
-
- def add_snippet(self, parent, snippet):
- piter = self.model.append(parent, ('', '', snippet))
-
- return self.snippet_changed(piter)
-
- def run(self):
- if not self.dlg:
- self.build()
- self.dlg.show()
- else:
- self.build_model()
- self.dlg.present()
-
-
- def snippet_from_iter(self, model, piter):
- parent = model.iter_parent(piter)
-
- if parent:
- return model.get_value(piter, self.OBJ_COLUMN)
- else:
- return None
-
- def language_snippets(self, model, parent, as_path=False):
- self.fill_if_needed(parent, False)
- piter = model.iter_children(parent)
- snippets = []
-
- if not piter:
- return snippets
-
- while piter:
- snippet = self.snippet_from_iter(model, piter)
-
- if snippet:
- if as_path:
- snippets.append(model.get_path(piter))
- else:
- snippets.append(snippet)
-
- piter = model.iter_next(piter)
-
- return snippets
-
- def selected_snippets(self, include_languages=True, as_path=False):
- selection = self.tree_view.get_selection()
- (model, paths) = selection.get_selected_rows()
- snippets = []
-
- if paths and len(paths) != 0:
- for p in paths:
- piter = model.get_iter(p)
- parent = model.iter_parent(piter)
-
- if not piter:
- continue
-
- if parent:
- snippet = self.snippet_from_iter(model, piter)
-
- if not snippet:
- continue
-
- if as_path:
- snippets.append(p)
- else:
- snippets.append(snippet)
- elif include_languages:
- snippets += self.language_snippets(model, piter, as_path)
-
- return snippets
-
- def selected_snippet(self):
- selection = self.tree_view.get_selection()
- (model, paths) = selection.get_selected_rows()
-
- if len(paths) == 1:
- piter = model.get_iter(paths[0])
- parent = model.iter_parent(piter)
- snippet = self.snippet_from_iter(model, piter)
-
- return parent, piter, snippet
- else:
- return None, None, None
-
- def selection_changed(self):
- if not self.snippet:
- sens = False
-
- self['entry_tab_trigger'].set_text('')
- self['entry_accelerator'].set_text('')
- self['source_view_snippet'].get_buffer().set_text('')
- self['combo_drop_targets'].child.set_text('')
-
- self.tooltips.disable()
- else:
- sens = True
-
- self['entry_tab_trigger'].set_text(self.snippet['tag'])
- self['entry_accelerator'].set_text( \
- self.snippet.accelerator_display())
- self['combo_drop_targets'].child.set_text(', '.join(self.snippet['drop-targets']))
-
- buf = self['source_view_snippet'].get_buffer()
- buf.set_text(self.snippet['text'])
-
- self.tooltips.enable()
-
- for name in ['source_view_snippet', 'label_tab_trigger',
- 'entry_tab_trigger', 'label_accelerator',
- 'entry_accelerator', 'label_drop_targets',
- 'combo_drop_targets']:
- self[name].set_sensitive(sens)
-
- self.update_buttons()
-
- def select_iter(self, piter, unselect=True):
- selection = self.tree_view.get_selection()
-
- if unselect:
- selection.unselect_all()
-
- selection.select_iter(piter)
-
- self.tree_view.scroll_to_cell(self.model.get_path(piter), None, \
- True, 0.5, 0.5)
-
- def get_language(self, path):
- if path[0] == 0:
- return None
- else:
- return self.model.get_value(self.model.get_iter( \
- (path[0],)), self.OBJ_COLUMN).get_id()
-
- def new_snippet(self, properties=None):
- if not self.language_path:
- return None
-
- snippet = Library().new_snippet(self.get_language(self.language_path), properties)
-
- return Snippet(snippet)
-
- def get_dummy(self, parent):
- if not self.model.iter_n_children(parent) == 1:
- return None
-
- dummy = self.model.iter_children(parent)
-
- if not self.model.get_value(dummy, self.OBJ_COLUMN):
- return dummy
-
- return None
-
- def unref_languages(self):
- piter = self.model.get_iter_first()
- library = Library()
-
- while piter:
- if self.is_filled(piter):
- language = self.get_language(self.model.get_path(piter))
- library.save(language)
-
- library.unref(language)
-
- piter = self.model.iter_next(piter)
-
- # Callbacks
- def on_dialog_snippets_destroy(self, dlg):
- # Remove temporary drag export
- if self._temp_export:
- shutil.rmtree(os.path.dirname(self._temp_export))
- self._temp_export = None
-
- if self.snippets_doc:
- self.snippets_doc.stop()
-
- self.default_size = [dlg.allocation.width, dlg.allocation.height]
- self.manager = None
-
- self.unref_languages()
- self.snippet = None
- self.model = None
- self.dlg = None
-
- def on_dialog_snippets_response(self, dlg, resp):
- if resp == gtk.RESPONSE_HELP:
- gedit.help_display(self.dlg, 'gedit', 'gedit-snippets-plugin')
- return
-
- self.dlg.destroy()
-
- def on_cell_editing_started(self, renderer, editable, path):
- piter = self.model.get_iter(path)
-
- if not self.model.iter_parent(piter):
- renderer.stop_editing(True)
- editable.remove_widget()
- elif isinstance(editable, gtk.Entry):
- if self.snippet:
- editable.set_text(self.snippet['description'])
- else:
- # This is the `Add a new snippet...` item
- editable.set_text('')
-
- editable.grab_focus()
-
- def on_cell_edited(self, cell, path, new_text):
- if new_text != '':
- piter = self.model.get_iter(path)
- node = self.model.get_value(piter, self.OBJ_COLUMN)
-
- if node:
- if node == self.snippet.data:
- s = self.snippet
- else:
- s = Snippet(node)
-
- s['description'] = new_text
- self.snippet_changed(piter)
- self.select_iter(piter)
- else:
- # This is the `Add a new snippet...` item
- # We create a new snippet
- snippet = self.new_snippet({'description': new_text})
-
- if snippet:
- self.model.set(piter, self.OBJ_COLUMN, snippet.data)
- self.snippet_changed(piter)
- self.snippet = snippet
- self.selection_changed()
-
- def on_entry_accelerator_focus_out(self, entry, event):
- if not self.snippet:
- return
-
- entry.set_text(self.snippet.accelerator_display())
-
- def entry_tab_trigger_update_valid(self):
- entry = self['entry_tab_trigger']
- text = entry.get_text()
-
- if text and not Library().valid_tab_trigger(text):
- img = self['image_tab_trigger']
- img.set_from_stock(gtk.STOCK_DIALOG_ERROR, gtk.ICON_SIZE_BUTTON)
- img.show()
-
- #self['hbox_tab_trigger'].set_spacing(3)
- tip = _('This is not a valid tab trigger. Triggers can either contain letters or a single, non alphanumeric, character like {, [, etcetera.')
-
- self.tooltips.set_tip(entry, tip)
- self.tooltips.set_tip(img, tip)
- else:
- self['image_tab_trigger'].hide()
- #self['hbox_tab_trigger'].set_spacing(0)
- self.tooltips.set_tip(entry, _('Single word with which the snippet is activated after pressing tab'))
-
- return False
-
- def on_entry_tab_trigger_focus_out(self, entry, event):
- if not self.snippet:
- return
-
- text = entry.get_text()
-
- # save tag
- self.snippet['tag'] = text
- self.snippet_changed()
-
- def on_entry_drop_targets_focus_out(self, entry, event):
- if not self.snippet:
- return
-
- text = entry.get_text()
-
- # save drop targets
- self.snippet['drop-targets'] = text
- self.snippet_changed()
-
- def on_entry_tab_trigger_changed(self, entry):
- self.entry_tab_trigger_update_valid()
-
- def on_source_view_snippet_focus_out(self, source_view, event):
- if not self.snippet:
- return
-
- buf = source_view.get_buffer()
- text = buf.get_text(buf.get_start_iter(), \
- buf.get_end_iter())
-
- self.snippet['text'] = text
- self.snippet_changed()
-
- def on_button_new_snippet_clicked(self, button):
- snippet = self.new_snippet()
-
- if not snippet:
- return
-
- parent = self.model.get_iter(self.language_path)
- path = self.model.get_path(parent)
-
- dummy = self.get_dummy(parent)
-
- if dummy:
- # Remove the dummy
- self.model.remove(dummy)
-
- # Add the snippet
- piter = self.add_snippet(parent, snippet.data)
- self.select_iter(piter)
-
- if not self.tree_view.row_expanded(path):
- self.tree_view.expand_row(path, False)
- self.select_iter(piter)
-
- self.tree_view.grab_focus()
-
- path = self.model.get_path(piter)
- self.tree_view.set_cursor(path, self.column, True)
-
- def file_filter(self, name, pattern):
- fil = gtk.FileFilter()
- fil.set_name(name)
-
- for p in pattern:
- fil.add_pattern(p)
-
- return fil
-
- def import_snippets(self, filenames):
- success = True
-
- for filename in filenames:
- if not gedit.utils.uri_has_file_scheme(filename):
- continue
-
- # Remove file://
- gfile = gio.File(filename)
- filename = gfile.get_path()
-
- importer = Importer(filename)
- error = importer.run()
-
- if error:
- message = _('The following error occurred while importing: %s') % error
- success = False
- message_dialog(self.dlg, gtk.MESSAGE_ERROR, message)
-
- self.build_model(True)
-
- if success:
- message = _('Import successfully completed')
- message_dialog(self.dlg, gtk.MESSAGE_INFO, message)
-
- def on_import_response(self, dialog, response):
- if response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_CLOSE:
- dialog.destroy()
- return
-
- f = dialog.get_uris()
- dialog.destroy()
-
- self.import_snippets(f)
-
- def on_button_import_snippets_clicked(self, button):
- dlg = gtk.FileChooserDialog(parent=self.dlg, title=_("Import snippets"),
- action=gtk.FILE_CHOOSER_ACTION_OPEN,
- buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
- gtk.STOCK_OPEN, gtk.RESPONSE_OK))
-
- dlg.add_filter(self.file_filter(_('All supported archives'), ('*.gz','*.bz2','*.tar', '*.xml')))
- dlg.add_filter(self.file_filter(_('Gzip compressed archive'), ('*.tar.gz',)))
- dlg.add_filter(self.file_filter(_('Bzip2 compressed archive'), ('*.tar.bz2',)))
- dlg.add_filter(self.file_filter(_('Single snippets file'), ('*.xml',)))
- dlg.add_filter(self.file_filter(_('All files'), '*'))
-
- dlg.connect('response', self.on_import_response)
- dlg.set_local_only(True)
-
- dlg.show()
-
- def export_snippets_real(self, filename, snippets, show_dialogs=True):
- export = Exporter(filename, snippets)
- error = export.run()
-
- if error:
- message = _('The following error occurred while exporting: %s') % error
- msgtype = gtk.MESSAGE_ERROR
- retval = False
- else:
- message = _('Export successfully completed')
- msgtype = gtk.MESSAGE_INFO
- retval = True
-
- if show_dialogs:
- message_dialog(self.dlg, msgtype, message)
-
- return retval
-
- def on_export_response(self, dialog, response):
- filename = dialog.get_filename()
- snippets = dialog._export_snippets
-
- dialog.destroy()
-
- if response != gtk.RESPONSE_OK:
- return
-
- self.export_snippets_real(filename, snippets);
-
- def export_snippets(self, filename=None, show_dialogs=True):
- snippets = self.selected_snippets()
-
- if not snippets or len(snippets) == 0:
- return False
-
- usersnippets = []
- systemsnippets = []
-
- # Iterate through snippets and look for system snippets
- for snippet in snippets:
- if snippet.can_modify():
- usersnippets.append(snippet)
- else:
- systemsnippets.append(snippet)
-
- export_snippets = snippets
-
- if len(systemsnippets) != 0 and show_dialogs:
- # Ask if system snippets should also be exported
- message = _('Do you want to include selected <b>system</b> snippets in your export?')
- mes = gtk.MessageDialog(flags=gtk.DIALOG_MODAL,
- type=gtk.MESSAGE_QUESTION,
- buttons=gtk.BUTTONS_YES_NO,
- message_format=message)
- mes.set_property('use-markup', True)
- resp = mes.run()
- mes.destroy()
-
- if resp == gtk.RESPONSE_NO:
- export_snippets = usersnippets
- elif resp != gtk.RESPONSE_YES:
- return False
-
- if len(export_snippets) == 0 and show_dialogs:
- message = _('There are no snippets selected to be exported')
- message_dialog(self.dlg, gtk.MESSAGE_INFORMATION, message)
- return False
-
- if not filename:
- dlg = gtk.FileChooserDialog(parent=self.dlg, title=_('Export snippets'),
- action=gtk.FILE_CHOOSER_ACTION_SAVE,
- buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
- gtk.STOCK_SAVE, gtk.RESPONSE_OK))
-
- dlg._export_snippets = export_snippets
- dlg.add_filter(self.file_filter(_('All supported archives'), ('*.gz','*.bz2','*.tar')))
- dlg.add_filter(self.file_filter(_('Gzip compressed archive'), ('*.tar.gz',)))
- dlg.add_filter(self.file_filter(_('Bzip2 compressed archive'), ('*.tar.bz2',)))
-
- dlg.add_filter(self.file_filter(_('All files'), '*'))
- dlg.set_do_overwrite_confirmation(True)
- dlg.set_current_name(self.default_export_name)
-
- dlg.connect('response', self.on_export_response)
- dlg.set_local_only(True)
-
- dlg.show()
- return True
- else:
- return self.export_snippets_real(filename, export_snippets, show_dialogs)
-
- def on_button_export_snippets_clicked(self, button):
- snippets = self.selected_snippets()
-
- if not snippets or len(snippets) == 0:
- return
-
- usersnippets = []
- systemsnippets = []
-
- # Iterate through snippets and look for system snippets
- for snippet in snippets:
- if snippet.can_modify():
- usersnippets.append(snippet)
- else:
- systemsnippets.append(snippet)
-
- dlg = gtk.FileChooserDialog(parent=self.dlg, title=_('Export snippets'),
- action=gtk.FILE_CHOOSER_ACTION_SAVE,
- buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
- gtk.STOCK_SAVE, gtk.RESPONSE_OK))
-
- dlg._export_snippets = snippets
-
- if len(systemsnippets) != 0:
- # Ask if system snippets should also be exported
- message = _('Do you want to include selected <b>system</b> snippets in your export?')
- mes = gtk.MessageDialog(flags=gtk.DIALOG_MODAL,
- type=gtk.MESSAGE_QUESTION,
- buttons=gtk.BUTTONS_YES_NO,
- message_format=message)
- mes.set_property('use-markup', True)
- resp = mes.run()
- mes.destroy()
-
- if resp == gtk.RESPONSE_NO:
- dlg._export_snippets = usersnippets
- elif resp != gtk.RESPONSE_YES:
- dlg.destroy()
- return
-
- if len(dlg._export_snippets) == 0:
- dlg.destroy()
-
- message = _('There are no snippets selected to be exported')
- message_dialog(self.dlg, gtk.MESSAGE_INFORMATION, message)
- return
-
- dlg.add_filter(self.file_filter(_('All supported archives'), ('*.gz','*.bz2','*.tar')))
- dlg.add_filter(self.file_filter(_('Gzip compressed archive'), ('*.tar.gz',)))
- dlg.add_filter(self.file_filter(_('Bzip2 compressed archive'), ('*.tar.bz2',)))
-
- dlg.add_filter(self.file_filter(_('All files'), '*'))
- dlg.set_do_overwrite_confirmation(True)
- dlg.set_current_name(self.default_export_name)
-
- dlg.connect('response', self.on_export_response)
- dlg.set_local_only(True)
-
- dlg.show()
-
- def remove_snippet_revert(self, path, piter):
- node = self.snippet_from_iter(self.model, piter)
- Library().revert_snippet(node)
-
- return piter
-
- def remove_snippet_delete(self, path, piter):
- node = self.snippet_from_iter(self.model, piter)
- parent = self.model.iter_parent(piter)
-
- Library().remove_snippet(node)
-
- if self.model.remove(piter):
- return piter
- elif path[-1] != 0:
- self.select_iter(self.model.get_iter((path[0], path[1] - 1)))
- else:
- dummy = self.add_new_snippet_node(parent)
- self.tree_view.expand_row(self.model.get_path(parent), False)
- return dummy
-
- def on_button_remove_snippet_clicked(self, button):
- override, remove, system = self.selected_snippets_state()
-
- if not (override ^ remove) or system:
- return
-
- paths = self.selected_snippets(include_languages=False, as_path=True)
-
- if override:
- action = self.remove_snippet_revert
- else:
- action = self.remove_snippet_delete
-
- # Remove selection
- self.tree_view.get_selection().unselect_all()
-
- # Create tree row references
- references = []
- for path in paths:
- references.append(gtk.TreeRowReference(self.model, path))
-
- # Remove/revert snippets
- select = None
- for reference in references:
- path = reference.get_path()
- piter = self.model.get_iter(path)
-
- res = action(path, piter)
-
- if res:
- select = res
-
- if select:
- self.select_iter(select)
-
- self.selection_changed()
-
- def set_accelerator(self, keyval, mod):
- accelerator = gtk.accelerator_name(keyval, mod)
- self.snippet['accelerator'] = accelerator
-
- return True
-
- def on_entry_accelerator_key_press(self, entry, event):
- source_view = self['source_view_snippet']
-
- if event.keyval == gdk.keyval_from_name('Escape'):
- # Reset
- entry.set_text(self.snippet.accelerator_display())
- self.tree_view.grab_focus()
-
- return True
- elif event.keyval == gdk.keyval_from_name('Delete') or \
- event.keyval == gdk.keyval_from_name('BackSpace'):
- # Remove the accelerator
- entry.set_text('')
- self.snippet['accelerator'] = ''
- self.tree_view.grab_focus()
-
- self.snippet_changed()
- return True
- elif Library().valid_accelerator(event.keyval, event.state):
- # New accelerator
- self.set_accelerator(event.keyval, \
- event.state & gtk.accelerator_get_default_mod_mask())
- entry.set_text(self.snippet.accelerator_display())
- self.snippet_changed()
- self.tree_view.grab_focus()
-
- else:
- return True
-
- def on_entry_accelerator_focus_in(self, entry, event):
- if self.snippet['accelerator']:
- entry.set_text(_('Type a new shortcut, or press Backspace to clear'))
- else:
- entry.set_text(_('Type a new shortcut'))
-
- def update_language_path(self):
- model, paths = self.tree_view.get_selection().get_selected_rows()
-
- # Check if all have the same language parent
- current_parent = None
-
- for path in paths:
- piter = model.get_iter(path)
- parent = model.iter_parent(piter)
-
- if parent:
- path = model.get_path(parent)
-
- if current_parent != None and current_parent != path:
- current_parent = None
- break
- else:
- current_parent = path
-
- self.language_path = current_parent
-
- def on_tree_view_selection_changed(self, selection):
- parent, piter, node = self.selected_snippet()
-
- if self.snippet:
- self.on_entry_tab_trigger_focus_out(self['entry_tab_trigger'],
- None)
- self.on_source_view_snippet_focus_out(self['source_view_snippet'],
- None)
- self.on_entry_drop_targets_focus_out(self['combo_drop_targets'].child,
- None)
-
- self.update_language_path()
-
- if node:
- self.snippet = Snippet(node)
- else:
- self.snippet = None
-
- self.selection_changed()
-
- def iter_after(self, target, after):
- if not after:
- return True
-
- tp = self.model.get_path(target)
- ap = self.model.get_path(after)
-
- if tp[0] > ap[0] or (tp[0] == ap[0] and (len(ap) == 1 or tp[1] > ap[1])):
- return True
-
- return False
-
- def on_tree_view_snippets_key_press(self, treeview, event):
- if event.keyval == gdk.keyval_from_name('Delete'):
- self.on_button_remove_snippet_clicked(None)
- return True
-
- def on_tree_view_snippets_row_expanded(self, treeview, piter, path):
- # Check if it is already filled
- self.fill_if_needed(piter)
- self.select_iter(piter)
-
- def on_entry_drop_targets_drag_data_received(self, entry, context, x, y, selection_data, info, timestamp):
- if not gtk.targets_include_uri(context.targets):
- return
-
- uris = drop_get_uris(selection_data)
-
- if not uris:
- return
-
- if entry.get_text():
- mimes = [entry.get_text()]
- else:
- mimes = []
-
- for uri in uris:
- try:
- mime = gio.content_type_guess(uri)
- except:
- mime = None
-
- if mime:
- mimes.append(mime)
-
- entry.set_text(', '.join(mimes))
- self.on_entry_drop_targets_focus_out(entry, None)
- context.finish(True, False, timestamp)
-
- entry.stop_emission('drag_data_received')
- # ex:ts=8:et:
-